package com.shelpe.service.simbaproxy.taobao;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.util.HTTPRequestUtils;
import com.shelpe.service.simbaproxy.client.AuthClient;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class APIParameterBuilderFilter extends ZuulFilter{
    
    private TaobaoAPIService taobaoAPIService;
    private AuthClient authClient;
    private ObjectMapper objectMapper;
   
    public int filterOrder(){
		return 38;
	}
	
	public String filterType(){
		return "pre";
	}
	
	public boolean shouldFilter(){
		RequestContext ctx = RequestContext.getCurrentContext();
		return (ctx.getRouteHost() != null && !ctx.containsKey("error.status_code"));
	}
	
	public Object run(){
        HttpServletRequest req = RequestContext.getCurrentContext().getRequest();
		
		String uri = req.getRequestURI();
		if(log.isDebugEnabled()){
			log.debug("uri : {}", uri);
			Enumeration<String> en = req.getParameterNames();
			while(en.hasMoreElements()){
				String key = en.nextElement();
				log.debug("parameter: {} - {}", key, req.getParameter(key));
			}
		
		}
		
		String[] methods = uri.split("/");
		String method = methods[methods.length - 1];
		List<String> attrList = new ArrayList<String>();
		attrList.add(method);
		
		Map<String, List<String> > params = HTTPRequestUtils.getInstance().getQueryParams();
		if(params == null){
			params = new HashMap<String, List<String> >();
		}
		
		params.put("method", attrList);
		
		AuthClient.UserToken token = null;
		if(req.getParameter("nick") != null){
			log.debug("pick up nick {} from parameter", req.getParameter("nick"));
			token = this.authClient.findSessionKeyByNick(req.getParameter("nick"));
		}else if(req.getHeader("tenantID") != null){
			log.debug("pick up tenantID {} from header", req.getHeader("tenantID"));
			token = this.authClient.findSessionKeyByID(NumberUtils.toLong(req.getHeader("tenantID")));
		}
		log.debug("token: {}", token);
		if(token != null && StringUtils.isNotBlank(token.getAccessToken())){
			attrList = new ArrayList<String>();
			attrList.add(token.getAccessToken());
			params.put("session", attrList);
		}else{
			log.error("can not fetch session key in {}", uri);
			SimbaErrorResponse res = new SimbaErrorResponse();
			res.setError(new SimbaErrorResponse.Error(-1, "invalid_token"));
			res.getError().setSubCode("access_token_not_found");
			res.getError().setSubMessage("找不到access token");
			String body = "";
			try {
				body = this.objectMapper.writeValueAsString(res);
			} catch (JsonProcessingException e) {
				log.error("JsonProcessingException: {}", e);
			}
			RequestContext.getCurrentContext().setResponseBody(body);
			RequestContext.getCurrentContext().setSendZuulResponse(false);
			return null;
		}
        
		taobaoAPIService.addCommParams(token != null && AuthClient.UserToken.TYPE_PURCHASE.equals(token.getType()), params);
		RequestContext.getCurrentContext().setRequestQueryParams(params);
		RequestContext.getCurrentContext().set("requestURI", "");
		
		if(log.isDebugEnabled()){
			Map<String, List<String> > paramss = HTTPRequestUtils.getInstance().getQueryParams();
			Set<Entry<String, List<String> > > entrySet = paramss.entrySet();
			for(Entry<String, List<String> > set : entrySet){
				log.info("parameter to taobao: {} - {}", set.getKey(), set.getValue().toString());
			}
		}
		
		RequestContext.getCurrentContext().set("metric_apiName", method);
		RequestContext.getCurrentContext().set("metric_startTime", System.currentTimeMillis());
		
		RequestContext.getCurrentContext().set("forword2taobao");
	
		
		return null;
	}

	public void setTaobaoAPIService(TaobaoAPIService taobaoAPIService) {
		this.taobaoAPIService = taobaoAPIService;
	}

	public void setAuthClient(AuthClient authClient) {
		this.authClient = authClient;
	}

	public void setObjectMapper(ObjectMapper objectMapper) {
		this.objectMapper = objectMapper;
	}

	
	

}